import pandas as pd
import numpy as np
import matplotlib
shotsdf = pd.read_csv('dat.csv')
shotsdf=shotsdf[shotsdf.SHOT_ZONE_BASIC!='Backcourt']
shotsdf=shotsdf[shotsdf.SHOT_ZONE_AREA!='Back court(BC)']
court_shapes = []
#Outer Lines
outer_lines_shape = dict(
type='rect',
xref='x',
yref='y',
x0='-250',
y0='-47.5',
x1='250',
y1='422.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(outer_lines_shape)
#Hoop Shape
hoop_shape = dict(
type='circle',
xref='x',
yref='y',
x0='7.5',
y0='7.5',
x1='-7.5',
y1='-7.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(hoop_shape)
#Basket Backboard
backboard_shape = dict(
type='rect',
xref='x',
yref='y',
x0='-30',
y0='-7.5',
x1='30',
y1='-6.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
),
fillcolor='rgba(10, 10, 10, 1)'
)
court_shapes.append(backboard_shape)
#Outer Box of Three-Second Area
outer_three_sec_shape = dict(
type='rect',
xref='x',
yref='y',
x0='-80',
y0='-47.5',
x1='80',
y1='143.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(outer_three_sec_shape)
#Inner Box of Three-Second Area
inner_three_sec_shape = dict(
type='rect',
xref='x',
yref='y',
x0='-60',
y0='-47.5',
x1='60',
y1='143.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(inner_three_sec_shape)
#Three Point Line (Left)
left_line_shape = dict(
type='line',
xref='x',
yref='y',
x0='-220',
y0='-47.5',
x1='-220',
y1='92.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(left_line_shape)
#Three Point Line (Right)
right_line_shape = dict(
type='line',
xref='x',
yref='y',
x0='220',
y0='-47.5',
x1='220',
y1='92.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(right_line_shape)
#Three Point Line Arc
three_point_arc_shape = dict(
type='path',
xref='x',
yref='y',
path='M -220 92.5 C -70 300, 70 300, 220 92.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(three_point_arc_shape)
#Center Circle
center_circle_shape = dict(
type='circle',
xref='x',
yref='y',
x0='60',
y0='482.5',
x1='-60',
y1='362.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(center_circle_shape)
#Restraining Circle
res_circle_shape = dict(
type='circle',
xref='x',
yref='y',
x0='20',
y0='442.5',
x1='-20',
y1='402.5',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(res_circle_shape)
#Free Throw Circle
free_throw_circle_shape = dict(
type='circle',
xref='x',
yref='y',
x0='60',
y0='200',
x1='-60',
y1='80',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
court_shapes.append(free_throw_circle_shape)
#Restricted Area
res_area_shape = dict(
type='circle',
xref='x',
yref='y',
x0='40',
y0='40',
x1='-40',
y1='-40',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1,
dash='dot'
)
)
court_shapes.append(res_area_shape)
def getZoneText(team, zone_name):
attempted = 0
#Center Three Pointer
if (zone_name == "center_3"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
#Left Center Three Pointer
elif (zone_name == "left_center_3"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side Center(LC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side Center(LC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
#Right Center Three Pointer
elif (zone_name == "right_center_3"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side Center(RC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side Center(RC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Above the Break 3')]['SHOT_MADE_FLAG'])
#Left Corner Three Pointer
elif (zone_name == "left_corner_3"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Left Corner 3')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Left Corner 3')]['SHOT_MADE_FLAG'])
#Right Corner Three Pointer
elif (zone_name == "right_corner_3"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Right Corner 3')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Right Corner 3')]['SHOT_MADE_FLAG'])
#Center Mid Range
elif (zone_name == "center_mid"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')]['SHOT_MADE_FLAG'])
#Left Center Mid Range
elif (zone_name == "left_center_mid"):
made = sum(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side Center(LC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side Center(LC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
#Right Center Mid Range
elif (zone_name == "right_center_mid"):
made = sum(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side Center(RC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side Center(RC)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
#Left Mid Range
elif (zone_name == "left_mid"):
made = sum(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Left Side(L)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
#Right Mid Range
elif (zone_name == "right_mid"):
made = sum(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[((shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'Mid-Range')) |
((shotsdf.TEAM_NAME ==team) &
(shotsdf.SHOT_ZONE_AREA == 'Right Side(R)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)'))]['SHOT_MADE_FLAG'])
#Paint (Not Restricted Area)
elif (zone_name == "paint"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_AREA == 'Center(C)')
& (shotsdf.SHOT_ZONE_BASIC == 'In The Paint (Non-RA)')]['SHOT_MADE_FLAG'])
#Restricted Area
elif (zone_name == "restricted_area"):
made = sum(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Restricted Area')]['SHOT_MADE_FLAG'])
attempted = len(shotsdf[(shotsdf.TEAM_NAME ==team)
& (shotsdf.SHOT_ZONE_BASIC == 'Restricted Area')]['SHOT_MADE_FLAG'])
if (attempted == 0): return ''
else: return "<b>{}-{}<br>{}</b>".format(made, attempted, round(made/attempted, 3))
def getZones():
zone_shapes = []
#Three Point Line Arc Top Left
zone1 = dict(
type='path',
xref='x',
yref='y',
path='M -250,92 L -220,92 C -187,140 -161,174 -80,228 L -95,350 L -250,350 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone1)
#Three Point Line Arc Top Right
zone2 = dict(
type='path',
xref='x',
yref='y',
path='M 250,92 L 220,92 C 187,140 161,174 80,228 L 95,350 L 250,350 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone2)
#Three Point Line Arc Top Center
zone3 = dict(
type='path',
xref='x',
yref='y',
path='M -80,228 C -50,240 0,266 80,228 L 95,350 L -95,350 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone3)
#Three Point Line Left Corner
zone4 = dict(
type='path',
xref='x',
yref='y',
path='M -250,-47.5 L -220,-47.5 L -220,92 L -250,92 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone4)
#Three Point Line Right Corner
zone5 = dict(
type='path',
xref='x',
yref='y',
path='M 250,-47.5 L 220,-47.5 L 220,92 L 250,92 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone5)
#Under the basket
zone6 = dict(
type='path',
xref='x',
yref='y',
path='M -40,-47.5 L -40,0 C -40,53 40,53 40,0 L 40,-47.5 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone6)
#Paint
zone7 = dict(
type='path',
xref='x',
yref='y',
path='M -60,-47.5 L -40,-47.5 L -40,0 C -40,53 40,53 40,0 L 40,-47.5 L 60,-47.5 L 60,143.5 L -60,143.5 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone7)
#Midrange Center
zone8 = dict(
type='path',
xref='x',
yref='y',
path='M -60,143.5 L -80,228 C -50,240 0,266 80,228 L 60,143.5 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone8)
#Midrange Center Left
zone8 = dict(
type='path',
xref='x',
yref='y',
path='M -220,92 C -187,140 -161,174 -80,228 L -60,143.5 L -60,92 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone8)
#Midrange Center Right
zone9 = dict(
type='path',
xref='x',
yref='y',
path='M 220,92 C 187,140 161,174 80,228 L 60,143.5 L 60,92 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone9)
#Midrange Left
zone10 = dict(
type='path',
xref='x',
yref='y',
path='M -220,-47.5 L -220,92 L -60,92 L -60,-47.5 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone10)
#Midrange Right
zone11 = dict(
type='path',
xref='x',
yref='y',
path='M 220,-47.5 L 220,92 L 60,92 L 60,-47.5 Z',
line=dict(
color='rgba(10, 10, 10, 1)',
width=1
)
)
zone_shapes.append(zone11)
return zone_shapes
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode(connected=True)
def updateVisibility(selectedTeam):
visibilityValues = []
for team in list(shotsdf.TEAM_NAME.unique()):
if team == selectedTeam:
visibilityValues.append(True) #shot_trace_made
visibilityValues.append(True) #shot_trace_missed
visibilityValues.append(True) #shot_zone_text
else:
visibilityValues.append(False)
visibilityValues.append(False)
visibilityValues.append(False)
return visibilityValues
zone_shapes = getZones()
data = []
buttons_data = []
for team in list(shotsdf.TEAM_NAME.unique()):
shot_trace_made = go.Scatter(
x = shotsdf[(shotsdf['EVENT_TYPE'] == 'Made Shot') & (shotsdf['TEAM_NAME'] == team)]['LOC_X'],
y = shotsdf[(shotsdf['EVENT_TYPE'] == 'Made Shot') & (shotsdf['TEAM_NAME'] == team)]['LOC_Y'],
mode = 'markers',
marker = dict(
size = 2,
color = 'rgba(63, 191, 63, 0.9)',
),
name = 'Made',
text = shotsdf[(shotsdf['EVENT_TYPE'] == 'Made Shot') & (shotsdf['TEAM_NAME'] == team)]['PLAYER_NAME'],
textposition = 'top left',
textfont = dict(
color = 'rgba(75, 85, 102,0.7)'
),
visible = (team =='Cle')
)
shot_trace_missed = go.Scatter(
x = shotsdf[(shotsdf['EVENT_TYPE'] == 'Missed Shot') & (shotsdf['TEAM_NAME'] == team)]['LOC_X'],
y = shotsdf[(shotsdf['EVENT_TYPE'] == 'Missed Shot') & (shotsdf['TEAM_NAME'] == team)]['LOC_Y'],
mode = 'markers',
marker = dict(
size = 2,
color = 'rgba(241, 18, 18, 0.9)',
),
name = 'Missed',
text = shotsdf[(shotsdf['EVENT_TYPE'] == 'Missed Shot') & (shotsdf['TEAM_NAME'] == team)]['PLAYER_NAME'],
textposition = 'top left',
textfont = dict(
color = 'rgba(75, 85, 102,0.7)'
),
visible = (team =='Cle')
)
shot_zones_text = go.Scatter(
x=[-175, 0, 175, -120, 0, 120, -190, -135, 0, 0, 135, 190],
y=[250, 300, 250, 140, 200, 140, -25, 40, 90, -10, 40, -25],
mode='text',
name='FG %',
text=[getZoneText(team, 'left_center_3'),
getZoneText(team, 'center_3'),
getZoneText(team, 'right_center_3'),
getZoneText(team, 'left_center_mid'),
getZoneText(team, 'center_mid'),
getZoneText(team, 'right_center_mid'),
getZoneText(team, 'left_corner_3'),
getZoneText(team, 'left_mid'),
getZoneText(team, 'paint'),
getZoneText(team, 'restricted_area'),
getZoneText(team, 'right_mid'),
getZoneText(team, 'right_corner_3')],
textposition='top center',
textfont = dict(
color = 'rgba(10, 10, 10, 1)',
size = 14
),
visible = (team == 'Cle')
)
data.append(shot_trace_made)
data.append(shot_trace_missed)
data.append(shot_zones_text)
buttons_data.append(
dict(
label = team,
method = 'update',
args = [{'visible': updateVisibility(team)},
{'shapes': court_shapes + getZones()}]
)
)
updatemenus = list([
dict(active=0,
buttons = buttons_data,
direction = 'down',
pad = {'r': 10, 't': 10},
showactive = True,
x = 0.21,
xanchor = 'left',
y = 1.19,
yanchor = 'top',
font = dict (
size = 14
)
)
])
layout = go.Layout(
title='Shot Chart for',
titlefont=dict(
size=14
),
hovermode = 'closest',
updatemenus = updatemenus,
showlegend = True,
height = 600,
width = 600,
shapes = court_shapes+zone_shapes,
xaxis = dict(
showticklabels = False,
range = [-250, 250]
),
yaxis = dict(
showticklabels = False,
range = [-47.5, 452.5]
)
)
fig = go.Figure(data=data, layout=layout)
iplot(fig)